home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / 3dvect39 / mod.asm < prev    next >
Assembly Source File  |  1994-10-30  |  34KB  |  1,084 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ; MOD playback routine using 'GUS' lowlevel GUS & SB routines.
  3. ;
  4. ; Written by: John McCarthy
  5. ;             1316 Redwood Lane
  6. ;             Pickering, Ontario.
  7. ;             Canada, Earth, Milky Way (for those out-of-towners)
  8. ;             L1X 1C5
  9. ;
  10. ; Most of the main MOD effects are implemented, Vibrato, Tone sliding, Volume
  11. ; Sliding and such.  I seem to have a little problem with the sample loop.  I
  12. ; dont think I am loading the loop start and end pointers correctly.  (I have
  13. ; one mod that clicks annoyingly when playing a certin sample.  But  I  can't
  14. ; figure out why the other players I have don't click  when  this  sample  is
  15. ; played).  All looped samples are bi-directionally looped.  This  means that
  16. ; intruments sound great when looped, but voices get really screwed up.   You
  17. ; can change the loop_bi option in the sample  loading  routine.   Anyway,  I
  18. ; coded this thing in about 3 days so don't expect too much.
  19. ;
  20. ; 4,6 or 8 channel mods are supported.  But only "31 sample" mods can be
  21. ; played. Sorry - 15 sample mods not supported.
  22. ;
  23. ; Send Me a Postcard!
  24. ;
  25. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  26.  
  27.          .386p
  28. code32   segment para public use32
  29.          assume cs:code32, ds:code32
  30.  
  31. include  pmode.ext
  32. include  gus.ext
  33. include  irq.ext
  34.  
  35. public   _mod_init, _mod_uninit, _mod_load, _mod_play, _mod_stop, _mod_sample_play
  36. public   _ordmod, _currow
  37.  
  38. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  39. ; DATA
  40. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  41.  
  42. ; memory usage
  43. ;
  44. ; samples first:  (496 bytes)
  45. ;  length    dd
  46. ;  volume    dd   ; xxqqyyzz  qq = loop yes/no, zz = fine tune, yy = volume
  47. ;  loopstart dd
  48. ;  loopend   dd
  49. ;
  50. ; pattern order   (128 bytes)
  51. ;
  52. ;  db 128 dup (0)
  53. ;
  54. ; patterns
  55. ;
  56. ;  db channels*4*64
  57.  
  58. ; Mod Pattern Info
  59. ;
  60. ;7654-3210 7654-3210 7654-3210 7654-3210
  61. ;wwww xxxxxxxxxxxxxx yyyy zzzzzzzzzzzzzz
  62. ;
  63. ;    wwwwyyyy (8 bits) is the sample for this channel/division (0 = no sample)
  64. ;xxxxxxxxxxxx (12 bits) is the sample's period (or effect parameter)
  65. ;zzzzzzzzzzzz (12 bits) is the effect for this channel/division
  66.  
  67. sambase  dd 0                               ; offset to sample data table
  68. ordbase  dd 0                               ; offset to pattern order
  69. patterns dd 0                               ; offset to patterns
  70. patternend dd 0
  71. whendone dd _ret                            ; routine to call when done module
  72.  
  73. _ordmod  db 0                               ; current order position (0-127 tables)
  74. _currow  db 0                               ; current row (0-63) set, but never used
  75. ordwidth dd 0                               ; 4,6 or 8
  76. ordsize  db 0                               ; number of patterns
  77. currow   dd 0                               ; order position row (offset in memory)
  78. lastord  db 0                               ; when does song end
  79.  
  80. panloc   db 0                               ; base of ping-pong pan
  81. tempo    db 0
  82. tempoc   db 0
  83. rowleft  db 0                               ; coloumns left before next order
  84. break    db 0
  85.  
  86. cursamp  db 8 dup (0)                       ; sample for channel
  87. modvol   db 8 dup (0)                       ; volume for channel (0-64)
  88. effect   dw 8 dup (0)                       ; channel effect
  89. portto   dw 8 dup (0)
  90. period   dw 8 dup (0)                       ; current sample period
  91. portparm db 8 dup (0)
  92. vibpos   db 8 dup (0)
  93. vibparm  db 8 dup (0)
  94. arp      dd 16 dup (0)                      ; dw index,arp,arp,arp
  95.  
  96.  
  97.          align 4
  98.  
  99. whichmodcontrol dd -1                       ; irq timing control number
  100.  
  101. pantbl   db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
  102.          db 12,12,12,11,11,10,9,8,7,6,5,4,4,3,3,3
  103.          db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
  104.          db 12,12,12,11,11,10,9,8,7,6,5,4,4,3,3,3
  105.          db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
  106.          db 12,12,12,11,11,10,9,8,7,6,5,4,4,3,3,3
  107.          db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
  108.          db 12,12,12,11,11,10,9,8,7,6,5,4
  109.  
  110. sintable db 0,25,50,74,98,120,142,162,180,197,212,225
  111.          db 236,244,250,254,255,254,250,244,236,225
  112.          db 212,197,180,162,142,120,98,74,50,25
  113.  
  114. pitchtbl dw 828 dup (0)
  115.  
  116. ;ax = 5.6865
  117. ;
  118. ;FOR z = 5 - 1 / 12 / 16 TO 0 STEP -1 / 12 / 16
  119. ; PRINT "dw "; INT(2 ^ (ax + z) + .5)
  120. ; q = q + 1
  121. ;NEXT z
  122. ;
  123. ;END
  124.  
  125. periods label word
  126. dw 1642,1636,1630,1624,1619,1613,1607,1601,1595,1590,1584,1578,1572,1567,1561
  127. dw 1556,1550,1544,1539,1533,1528,1522,1517,1511,1506,1500,1495,1490,1484,1479
  128. dw 1474,1468,1463,1458,1452,1447,1442,1437,1432,1426,1421,1416,1411,1406,1401
  129. dw 1396,1391,1386,1381,1376,1371,1366,1361,1356,1351,1346,1341,1337,1332,1327
  130. dw 1322,1317,1313,1308,1303,1299,1294,1289,1285,1280,1275,1271,1266,1262,1257
  131. dw 1253,1248,1244,1239,1235,1230,1226,1221,1217,1213,1208,1204,1199,1195,1191
  132. dw 1187,1182,1178,1174,1170,1165,1161,1157,1153,1149,1144,1140,1136,1132,1128
  133. dw 1124,1120,1116,1112,1108,1104,1100,1096,1092,1088,1084,1080,1076,1072,1069
  134. dw 1065,1061,1057,1053,1049,1046,1042,1038,1034,1031,1027,1023,1020,1016,1012
  135. dw 1009,1005,1001,998,994,991,987,983,980,976,973,969,966,962,959,955,952,949
  136. dw 945,942,938,935,932,928,925,922,918,915,912,908,905,902,899,895,892,889,886
  137. dw 882,879,876,873,870,867,864,860,857,854,851,848,845,842,839,836,833,830,827
  138. dw 824,821,818,815,812,809,806,803,801,798,795,792,789,786,783,781,778,775,772
  139. dw 769,767,764,761,758,756,753,750,747,745,742,739,737,734,731,729,726,724,721
  140. dw 718,716,713,711,708,706,703,700,698,695,693,690,688,685,683,680,678,676,673
  141. dw 671,668,666,664,661,659,656,654,652,649,647,645,642,640,638,635,633,631,629
  142. dw 626,624,622,620,617,615,613,611,608,606,604,602,600,598,595,593,591,589,587
  143. dw 585,583,581,578,576,574,572,570,568,566,564,562,560,558,556,554,552,550,548
  144. dw 546,544,542,540,538,536,534,532,530,529,527,525,523,521,519,517,515,513,512
  145. dw 510,508,506,504,502,501,499,497,495,493,492,490,488,486,485,483,481,479,478
  146. dw 476,474,473,471,469,467,466,464,462,461,459,457,456,454,453,451,449,448,446
  147. dw 444,443,441,440,438,436,435,433,432,430,429,427,426,424,423,421,419,418,416
  148. dw 415,413,412,411,409,408,406,405,403,402,400,399,397,396,395,393,392,390,389
  149. dw 387,386,385,383,382,381,379,378,376,375,374,372,371,370,368,367,366,364,363
  150. dw 362,360,359,358,357,355,354,353,351,350,349,348,346,345,344,343,341,340,339
  151. dw 338,337,335,334,333,332,331,329,328,327,326,325,323,322,321,320,319,318,317
  152. dw 315,314,313,312,311,310,309,308,306,305,304,303,302,301,300,299,298,297,296
  153. dw 294,293,292,291,290,289,288,287,286,285,284,283,282,281,280,279,278,277,276
  154. dw 275,274,273,272,271,270,269,268,267,266,265,264,263,262,261,260,260,259,258
  155. dw 257,256,255,254,253,252,251,250,249,249,248,247,246,245,244,243,242,241,241
  156. dw 240,239,238,237,236,235,235,234,233,232,231,230,230,229,228,227,226,225,225
  157. dw 224,223,222,221,221,220,219,218,217,217,216,215,214,214,213,212,211,211,210
  158. dw 209,208,207,207,206,205,205,204,203,202,202,201,200,199,199,198,197,197,196
  159. dw 195,194,194,193,192,192,191,190,190,189,188,188,187,186,186,185,184,184,183
  160. dw 182,182,181,180,180,179,178,178,177,176,176,175,174,174,173,173,172,171,171
  161. dw 170,170,169,168,168,167,166,166,165,165,164,164,163,162,162,161,161,160,159
  162. dw 159,158,158,157,157,156,155,155,154,154,153,153,152,152,151,150,150,149,149
  163. dw 148,148,147,147,146,146,145,145,144,144,143,143,142,142,141,140,140,139,139
  164. dw 138,138,137,137,136,136,136,135,135,134,134,133,133,132,132,131,131,130,130
  165. dw 129,129,128,128,127,127,127,126,126,125,125,124,124,123,123,122,122,122,121
  166. dw 121,120,120,119,119,119,118,118,117,117,116,116,116,115,115,114,114,114,113
  167. dw 113,112,112,112,111,111,110,110,110,109,109,108,108,108,107,107,106,106,106
  168. dw 105,105,104,104,104,103,103,103,102,102,102,101,101,100,100,100,99,99,99,98
  169. dw 98,98,97,97,97,96,96,95,95,95,94,94,94,93,93,93,92,92,92,91,91,91,90,90,90
  170. dw 89,89,89,89,88,88,88,87,87,87,86,86,86,85,85,85,84,84,84,84,83,83,83,82,82
  171. dw 82,81,81,81,81,80,80,80,79,79,79,79,78,78,78,77,77,77,77,76,76,76,76,75,75
  172. dw 75,74,74,74,74,73,73,73,73,72,72,72,72,71,71,71,71,70,70,70,69,69,69,69,68
  173. dw 68,68,68,68,67,67,67,67,66,66,66,66,65,65,65,65,64,64,64,64,63,63,63,63,63
  174. dw 62,62,62,62,61,61,61,61,61,60,60,60,60,60,59,59,59,59,58,58,58,58,58,57,57
  175.  
  176. ;ax = 11.08082
  177. ;
  178. ;FOR z = 0 TO 5 STEP 1 / 12 / 16
  179. ; PRINT "dw "; INT(2 ^ (ax + z) + .5)
  180. ; q = q + 1
  181. ;NEXT z
  182. ;
  183. ;END
  184.  
  185. rawfreq label word
  186. dw 2166,2174,2182,2190,2198,2205,2213,2221,2229,2238,2246,2254,2262,2270,2278
  187. dw 2287,2295,2303,2311,2320,2328,2337,2345,2354,2362,2371,2379,2388,2396,2405
  188. dw 2414,2422,2431,2440,2449,2458,2467,2476,2484,2493,2502,2512,2521,2530,2539
  189. dw 2548,2557,2567,2576,2585,2594,2604,2613,2623,2632,2642,2651,2661,2671,2680
  190. dw 2690,2700,2709,2719,2729,2739,2749,2759,2769,2779,2789,2799,2809,2819,2829
  191. dw 2840,2850,2860,2870,2881,2891,2902,2912,2923,2933,2944,2955,2965,2976,2987
  192. dw 2998,3008,3019,3030,3041,3052,3063,3074,3085,3097,3108,3119,3130,3142,3153
  193. dw 3164,3176,3187,3199,3210,3222,3234,3245,3257,3269,3281,3293,3304,3316,3328
  194. dw 3340,3353,3365,3377,3389,3401,3414,3426,3438,3451,3463,3476,3488,3501,3514
  195. dw 3526,3539,3552,3565,3578,3591,3604,3617,3630,3643,3656,3669,3682,3696,3709
  196. dw 3723,3736,3750,3763,3777,3790,3804,3818,3832,3845,3859,3873,3887,3901,3916
  197. dw 3930,3944,3958,3972,3987,4001,4016,4030,4045,4059,4074,4089,4104,4118,4133
  198. dw 4148,4163,4178,4194,4209,4224,4239,4255,4270,4285,4301,4316,4332,4348,4363
  199. dw 4379,4395,4411,4427,4443,4459,4475,4491,4507,4524,4540,4557,4573,4590,4606
  200. dw 4623,4640,4656,4673,4690,4707,4724,4741,4758,4776,4793,4810,4828,4845,4863
  201. dw 4880,4898,4915,4933,4951,4969,4987,5005,5023,5041,5059,5078,5096,5115,5133
  202. dw 5152,5170,5189,5208,5227,5245,5264,5284,5303,5322,5341,5360,5380,5399,5419
  203. dw 5438,5458,5478,5498,5517,5537,5557,5578,5598,5618,5638,5659,5679,5700,5720
  204. dw 5741,5762,5783,5803,5824,5846,5867,5888,5909,5931,5952,5974,5995,6017,6039
  205. dw 6060,6082,6104,6126,6149,6171,6193,6216,6238,6261,6283,6306,6329,6352,6375
  206. dw 6398,6421,6444,6467,6491,6514,6538,6561,6585,6609,6633,6657,6681,6705,6729
  207. dw 6754,6778,6803,6827,6852,6877,6902,6926,6952,6977,7002,7027,7053,7078,7104
  208. dw 7129,7155,7181,7207,7233,7259,7286,7312,7338,7365,7392,7418,7445,7472,7499
  209. dw 7526,7553,7581,7608,7636,7663,7691,7719,7747,7775,7803,7831,7859,7888,7916
  210. dw 7945,7974,8003,8031,8061,8090,8119,8148,8178,8207,8237,8267,8297,8327,8357
  211. dw 8387,8417,8448,8478,8509,8540,8571,8602,8633,8664,8695,8727,8758,8790,8822
  212. dw 8854,8886,8918,8950,8983,9015,9048,9080,9113,9146,9179,9212,9246,9279,9313
  213. dw 9346,9380,9414,9448,9482,9517,9551,9586,9620,9655,9690,9725,9760,9796,9831
  214. dw 9867,9902,9938,9974,10010,10046,10083,10119,10156,10192,10229,10266,10303
  215. dw 10341,10378,10416,10453,10491,10529,10567,10605,10644,10682,10721,10759
  216. dw 10798,10837,10877,10916,10955,10995,11035,11075,11115,11155,11195,11236
  217. dw 11276,11317,11358,11399,11440,11482,11523,11565,11607,11649,11691,11733
  218. dw 11776,11818,11861,11904,11947,11990,12034,12077,12121,12165,12209,12253
  219. dw 12297,12342,12386,12431,12476,12521,12566,12612,12657,12703,12749,12795
  220. dw 12841,12888,12935,12981,13028,13075,13123,13170,13218,13266,13314,13362
  221. dw 13410,13459,13507,13556,13605,13654,13704,13753,13803,13853,13903,13953
  222. dw 14004,14054,14105,14156,14207,14259,14310,14362,14414,14466,14519,14571
  223. dw 14624,14677,14730,14783,14836,14890,14944,14998,15052,15107,15161,15216
  224. dw 15271,15326,15382,15437,15493,15549,15606,15662,15719,15775,15833,15890
  225. dw 15947,16005,16063,16121,16179,16238,16296,16355,16415,16474,16533,16593
  226. dw 16653,16714,16774,16835,16896,16957,17018,17079,17141,17203,17265,17328
  227. dw 17391,17453,17517,17580,17644,17707,17771,17836,17900,17965,18030,18095
  228. dw 18161,18226,18292,18358,18425,18491,18558,18625,18693,18760,18828,18896
  229. dw 18965,19033,19102,19171,19240,19310,19380,19450,19520,19591,19662,19733
  230. dw 19804,19876,19948,20020,20092,20165,20238,20311,20384,20458,20532,20606
  231. dw 20681,20756,20831,20906,20982,21058,21134,21210,21287,21364,21441,21519
  232. dw 21597,21675,21753,21832,21911,21990,22069,22149,22229,22310,22390,22471
  233. dw 22553,22634,22716,22798,22881,22963,23047,23130,23214,23298,23382,23466
  234. dw 23551,23636,23722,23808,23894,23980,24067,24154,24241,24329,24417,24505
  235. dw 24594,24683,24772,24862,24952,25042,25132,25223,25315,25406,25498,25590
  236. dw 25683,25776,25869,25962,26056,26151,26245,26340,26435,26531,26627,26723
  237. dw 26820,26917,27014,27112,27210,27308,27407,27506,27606,27705,27806,27906
  238. dw 28007,28108,28210,28312,28415,28517,28620,28724,28828,28932,29037,29142
  239. dw 29247,29353,29459,29566,29673,29780,29888,29996,30104,30213,30322,30432
  240. dw 30542,30652,30763,30875,30986,31098,31211,31324,31437,31551,31665,31779
  241. dw 31894,32010,32125,32241,32358,32475,32593,32710,32829,32947,33067,33186
  242. dw 33306,33427,33548,33669,33791,33913,34036,34159,34282,34406,34531,34655
  243. dw 34781,34907,35033,35160,35287,35414,35542,35671,35800,35929,36059,36190
  244. dw 36321,36452,36584,36716,36849,36982,37116,37250,37385,37520,37656,37792
  245. dw 37929,38066,38204,38342,38481,38620,38759,38900,39040,39181,39323,39465
  246. dw 39608,39751,39895,40039,40184,40330,40475,40622,40769,40916,41064,41213
  247. dw 41362,41511,41662,41812,41963,42115,42268,42420,42574,42728,42882,43037
  248. dw 43193,43349,43506,43663,43821,43980,44139,44299,44459,44620,44781,44943
  249. dw 45105,45269,45432,45597,45762,45927,46093,46260,46427,46595,46764,46933
  250. dw 47103,47273,47444,47615,47788,47961,48134,48308,48483,48658,48834,49011
  251. dw 49188,49366,49544,49724,49903,50084,50265,50447,50629,50812,50996,51181
  252. dw 51366,51552,51738,51925,52113,52301,52491,52680,52871,53062,53254,53447
  253. dw 53640,53834,54029,54224,54420,54617,54815,55013,55212,55412,55612,55813
  254. dw 56015,56218,56421,56625,56830,57035,57242,57449,57656,57865,58074,58284
  255. dw 58495,58707,58919,59132,59346,59561,59776,59992,60209,60427,60645,60865
  256. dw 61085,61306,61528,61750,61973
  257.  
  258. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  259. ; Main playback routine called by IRQ routine
  260. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  261.  
  262. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  263. ; mr_???? main mod playing effects handler (called only as often as tempo requires)
  264. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  265.  
  266. mr_modpolling:
  267.          dec tempoc
  268.          jnz fx_between_rows
  269.  
  270.          inc panloc
  271.          and panloc,3fh
  272.  
  273.          mov esi,currow
  274.          xor ebp,ebp
  275. mr_mainloop:
  276.          movzx eax,panloc
  277.          lea eax,[eax+ebp*4]
  278.          mov bl,pantbl[eax+ebp*4]
  279.          mov _vcpan[ebp],bl
  280.          or _vccmnd[ebp],pan
  281.  
  282.          lodsw
  283.          xchg al,ah
  284.          mov bl,ah
  285.          and ah,0fh
  286.          mov cx,ax
  287.          lodsw
  288.          xchg al,ah
  289.          mov bh,ah
  290.          and ah,0fh
  291.          mov dx,ax
  292.          mov effect[ebp*2],dx
  293.          and bl,0F0h
  294.          shr bh,4
  295.  
  296.          or bl,bh
  297.          je mr_nosample
  298.  
  299.          and ebx,0ffh                       ; play new sample
  300.          dec ebx
  301.          mov edi,ebx
  302.          mov cursamp[ebp],bl
  303.  
  304.          shl edi,4
  305.          add edi,sambase
  306.  
  307.          mov eax,[edi]
  308.          mov _vcsbeg[ebp*4],eax
  309.          mov eax,[edi+8]
  310.          mov _vclbeg[ebp*4],eax
  311.          mov eax,[edi+12]
  312.          mov _vclend[ebp*4],eax
  313.  
  314.          mov al,byte ptr [edi+4+1]
  315.          mov modvol[ebp],al
  316.          mov al,modvol[ebp]
  317.          cmp al,63
  318.          jb short mr_novol64
  319.          mov al,63
  320. mr_novol64:
  321.          shr al,2
  322.          mov _vcvol[ebp],al
  323.  
  324.          mov al,byte ptr [edi+4+2]
  325.          mov _vccntrl[ebp],al
  326.          or _vccmnd[ebp],play+vol+freq+pan
  327.  
  328. mr_nosample:
  329.          test cx,cx                         ; set new pitch
  330.          je short mr_testtempo
  331.  
  332.          mov portto[ebp*2],cx
  333.  
  334.          cmp dh,3
  335.          je short mr_testtempo
  336.  
  337.          mov period[ebp*2],cx
  338.          sub ecx,57
  339.          and ecx,0fffeh
  340.          mov ax,pitchtbl[ecx]
  341.          mov _vcfreq[ebp*2],ax
  342.          or _vccmnd[ebp],freq
  343. mr_testtempo:
  344.          test dx,dx
  345.          je mr_done_channel
  346.  
  347.          cmp dh,0fh                         ; set tempo
  348.          jne short mr_jump
  349.  
  350.          test dl,dl
  351.          je mr_done_channel
  352.  
  353.          cmp dl,31
  354.          ja short mr_setbpm
  355.  
  356.          mov tempo,dl
  357.          mov tempoc,dl
  358.          jmp mr_done_channel
  359.  
  360. mr_setbpm:
  361.          mov eax,900
  362.          movzx ebx,dl
  363.          xor edx,edx
  364.          div bx
  365.          mov tempo,al
  366.          mov tempoc,al
  367.          jmp mr_done_channel
  368. mr_jump:
  369.          cmp dh,0bh                         ; jump to new pattern
  370.          jne short mr_break
  371.          mov _ordmod,dl
  372.          mov rowleft,1
  373.          jmp mr_done_channel
  374. mr_break:
  375.          cmp dh,0dh                         ; pattern break
  376.          jne short mr_setvolume
  377.  
  378.          mov dh,dl
  379.          and dl,0fh
  380.          shr dh,4
  381.          add dh,dh
  382.          add dl,dh
  383.          shl dh,2
  384.          add dl,dh
  385.          mov break,dl
  386.          mov rowleft,1
  387.          jmp mr_done_channel
  388.  
  389. mr_setvolume:
  390.          cmp dh,0ch                         ; set volume
  391.          jne short mr_tone_slide
  392.  
  393.          mov modvol[ebp],dl
  394.          cmp dl,63
  395.          jbe short mr_not_6chan4
  396.          mov dl,63
  397. mr_not_6chan4:
  398.          shr dl,2
  399.          mov _vcvol[ebp],dl
  400.          or _vccmnd[ebp],vol
  401.          jmp mr_done_channel
  402.  
  403. mr_tone_slide:
  404.          cmp dh,3                           ; tone slide
  405.          jne short mr_init_vibrato
  406.  
  407.          test dl,dl
  408.          jne short mr_notlastslide
  409.          mov dl,[ebp+portparm]
  410. mr_notlastslide:
  411.          mov [ebp+portparm],dl
  412.          mov [ebp*2+effect],dx
  413.          and _vccmnd[ebp],-1-play
  414.          jmp mr_done_channel
  415.  
  416. mr_init_vibrato:
  417.          cmp dh,4                           ; initialize vibrato
  418.          jne short mr_initarp
  419.  
  420.          mov al,[ebp+vibparm]
  421.          mov ah,al
  422.          and al,0fh
  423.          and ah,0f0h
  424.          test dl,0fh
  425.          jne short mr_okdepth
  426.          or dl,al
  427. mr_okdepth:
  428.          test dl,0f0h
  429.          jne short mr_okrate
  430.          or dl,ah
  431. mr_okrate:
  432.          mov [ebp+vibparm],dl
  433.          mov [ebp*2+effect],dx
  434.          test cx,cx
  435.          je mr_done_channel
  436.          mov [ebp+vibpos],0
  437.          jmp mr_done_channel
  438.  
  439. mr_initarp:
  440.          cmp dh,0                           ; initialize arpeggio
  441.          jne mr_more_effects
  442.  
  443.          mov dh,dl
  444.          and dl,0fh
  445.          shr dh,4
  446.          xor ebx,ebx
  447.          mov ax,[ebp*2+period]
  448.  
  449. mr_scanperiod:
  450.          cmp ax,periods[ebx*2]
  451.          jae mr_set_arp
  452.          inc ebx
  453.          cmp ebx,930
  454.          jb short mr_scanperiod
  455. mr_set_arp:
  456.          xor eax,eax
  457.          mov al,dh
  458.          shl eax,4
  459.          add eax,ebx
  460.  
  461.          xor ecx,ecx
  462.          mov cl,dl
  463.          shl ecx,4
  464.          add ecx,ebx
  465.  
  466.          mov bx,periods[ebx*2]
  467.          sub ebx,57
  468.          and ebx,0fffeh
  469.          mov bx,[pitchtbl+ebx]
  470.          mov word ptr [ebp*8+arp+2],bx
  471.  
  472.          mov cx,periods[ecx*2]
  473.          sub ecx,57
  474.          and ecx,0fffeh
  475.          mov cx,[pitchtbl+ecx]
  476.          mov word ptr [ebp*8+arp+4],cx
  477.  
  478.          mov ax,periods[eax*2]
  479.          sub eax,57
  480.          and eax,0fffeh
  481.          mov ax,[pitchtbl+eax]
  482.          mov word ptr [ebp*8+arp+6],ax
  483.  
  484.          mov byte ptr [ebp*8+arp],0
  485.          jmp mr_done_channel
  486.  
  487. mr_more_effects:
  488.  
  489. ; Put more effects here
  490.  
  491. ; dh = effect
  492. ; dl = data
  493.  
  494. mr_done_channel:
  495.          inc ebp
  496.          cmp ordwidth,ebp
  497.          jne mr_mainloop
  498.  
  499.          mov currow,esi                     ; save current pattern position
  500.  
  501.          inc _currow
  502.          dec rowleft                        ; how many rows left?
  503.          jnz mr_nonewrow
  504.  
  505.          inc _ordmod                        ; done pattern, find next
  506.          movzx eax,_ordmod
  507.          cmp al,lastord                     ; done song?
  508.          jne short mr_moresong
  509.          xor eax,eax                        ; set up to loop forever unless user calls _mod_stop
  510.          mov _ordmod,al
  511.          call [whendone]                    ; call user routine when finished mod
  512. mr_moresong:
  513.          add eax,ordbase
  514.          movzx eax,byte ptr [eax]
  515.          shl eax,10
  516.          cmp ordwidth,8
  517.          jne short mr_not_8chan
  518.          shl eax,1
  519. mr_not_8chan:
  520.          cmp ordwidth,6
  521.          jne short mr_not_6chan
  522.          mov ebx,eax
  523.          shr ebx,1
  524.          add eax,ebx
  525. mr_not_6chan:
  526.          add eax,patterns
  527.          mov currow,eax
  528.          movzx eax,break
  529.          mov ebx,ordwidth
  530.          shl eax,4
  531.          cmp ebx,8
  532.          jne short mr_not_8chanbrk
  533.          shl eax,1
  534. mr_not_8chanbrk:
  535.          cmp ebx,6
  536.          jne short mr_not_6chanbrk
  537.          mov ecx,eax
  538.          shr ecx,1
  539.          add eax,ecx
  540. mr_not_6chanbrk:
  541.          add currow,eax
  542.          mov rowleft,64
  543.          mov _currow,0
  544.          mov break,0
  545. mr_nonewrow:
  546.          mov al,tempo
  547.          mov tempoc,al
  548.          ret
  549.  
  550. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  551. ; fx_???? effects handler called in between rows (called every IRQ)
  552. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  553.  
  554. fx_between_rows:
  555.          mov ebp,ordwidth
  556.          dec ebp
  557. fx_mainloop:
  558.          mov dx,[effect+ebp*2]
  559.          test dx,dx
  560.          je fx_doneeffect
  561.  
  562.          cmp dh,0ah                         ; volume slide
  563.          jne short fx_portamento_up
  564.  
  565.          mov dh,dl
  566.          and dl,0fh
  567.          shr dh,3                           ; 4
  568.          mov al,[ebp+modvol]
  569.          sub al,dl
  570.          cmp al,65
  571.          jb short fx_vollow
  572.          xor al,al
  573. fx_vollow:
  574.          add al,dh
  575.          cmp al,64
  576.          jbe short fx_volhigh
  577.          mov al,64
  578. fx_volhigh:
  579.          mov [ebp+modvol],al
  580.          cmp al,63
  581.          jb short fx_not64
  582.          mov al,63
  583. fx_not64:
  584.          shr al,2
  585.          mov _vcvol[ebp],al
  586.          or _vccmnd[ebp],vol
  587.          jmp fx_doneeffect
  588. fx_portamento_up:
  589.          cmp dh,01h                         ; portup
  590.          jne short fx_portamento_down
  591.  
  592.          xor dh,dh
  593.          mov bx,period[ebp*2]
  594.          sub bx,dx
  595.          cmp bx,57
  596.          jae short fx_notbelow
  597.          mov bx,57
  598. fx_notbelow:
  599.          mov period[ebp*2],bx
  600.          sub ebx,57
  601.          and ebx,0fffeh
  602.          mov bx,pitchtbl[ebx]
  603.          mov _vcfreq[ebp*2],bx
  604.          or _vccmnd[ebp],freq
  605.          jmp fx_doneeffect
  606.  
  607. fx_portamento_down:
  608.          cmp dh,02h                         ; portdown
  609.          jne short fx_volumeslide
  610.  
  611.          xor dh,dh
  612.          mov bx,period[ebp*2]
  613.          add bx,dx
  614.          cmp bx,1711
  615.          jb short fx_nooverflow
  616.          mov bx,1711
  617. fx_nooverflow:
  618.          mov period[ebp*2],bx
  619.          sub ebx,57
  620.          and ebx,0fffeh
  621.          mov bx,pitchtbl[ebx]
  622.          mov _vcfreq[ebp*2],bx
  623.          or _vccmnd[ebp],freq
  624.          jmp fx_doneeffect
  625.  
  626. fx_volumeslide:
  627.          cmp dh,05h                         ; handle volume slide
  628.          jne short fx_tone_slide
  629.  
  630.          mov dh,dl
  631.          and dl,0fh
  632.          shr dh,3                           ; 4
  633.          mov al,[ebp+modvol]
  634.          sub al,dl
  635.          cmp al,65
  636.          jb fx_volunder
  637.          xor al,al
  638. fx_volunder:
  639.          add al,dh
  640.          cmp al,64
  641.          jbe fx_volover
  642.          mov al,64
  643. fx_volover:
  644.          mov [ebp+modvol],al
  645.          cmp al,63
  646.          jb short fx_vol63
  647.          mov al,63
  648. fx_vol63:
  649.          shr al,2
  650.          mov _vcvol[ebp],al
  651.          or _vccmnd[ebp],vol
  652.  
  653.          mov dh,3
  654.          mov dl,[portparm+ebp]
  655. fx_tone_slide:
  656.          cmp dh,3                           ; tone slide
  657.          jne fx_vibrato
  658.  
  659.          xor dh,dh
  660.          mov ax,[ebp*2+portto]
  661.          mov bx,[ebp*2+period]
  662.          cmp bx,ax
  663.          je fx_doneeffect
  664.          jg short fx_toneup
  665. fx_tonedown:
  666.          add bx,dx
  667.          cmp bx,ax
  668.          jle short fx_settone
  669. fx_underflow:
  670.          mov bx,ax
  671.          jmp short fx_settone
  672. fx_toneup:
  673.          sub bx,dx
  674.          cmp bx,ax
  675.          jl short fx_underflow
  676. fx_settone:
  677.          mov [ebp*2+period],bx
  678.          sub bx,57
  679.          and ebx,0fffeh
  680.          mov ax,pitchtbl[ebx]
  681.          mov _vcfreq[ebp*2],ax
  682.          or _vccmnd[ebp],freq
  683.          jmp fx_doneeffect
  684.  
  685. fx_vibslide:
  686.          cmp dh,6                           ; volume slide + vibrato
  687.          jne fx_vibrato
  688.  
  689.          mov dh,dl
  690.          and dl,0fh
  691.          shr dh,3                           ; 4
  692.          mov al,[ebp+modvol]
  693.          sub al,dl
  694.          cmp al,65
  695.          jb short fx_vlunder
  696.          xor al,al
  697. fx_vlunder:
  698.          add al,dh
  699.          cmp al,64
  700.          jbe short fx_vlover
  701.          mov al,64
  702. fx_vlover:
  703.          mov [ebp+modvol],al
  704.          cmp al,63
  705.          jb short fx_vl63
  706.          mov al,63
  707. fx_vl63:
  708.          shr al,2
  709.          mov _vcvol[ebp],al
  710.          or _vccmnd[ebp],vol
  711.  
  712.          mov dh,4
  713.          mov dl,vibparm[ebp]
  714.  
  715. fx_vibrato:
  716.          cmp dh,4                           ; vibrato
  717.          jne fx_arp
  718.  
  719.          mov dh,dl
  720.          and dl,0fh
  721.          shr dh,4
  722.          shl dh,2
  723.          add [ebp+vibpos],dh
  724.          mov dh,[ebp+vibpos]
  725.          mov bl,dh
  726.          shr bl,2
  727.          and ebx,1fh
  728.          mov al,[sintable+ebx]
  729.          mul dl
  730.          rol ax,1
  731.          xchg al,ah
  732.          and ah,1
  733.          test dh,dh
  734.          jns fx_vibup
  735.          neg ax
  736. fx_vibup:
  737.          add ax,[ebp*2+period]
  738.          mov bx,ax
  739.          cmp bx,57
  740.          jge short fx_nolovib
  741.          mov bx,57
  742. fx_nolovib:
  743.          cmp bx,1712
  744.          jle short fx_nohivib
  745.          mov bx,1712
  746. fx_nohivib:
  747.          sub ebx,57
  748.          and ebx,0fffeh
  749.          mov ax,pitchtbl[ebx]
  750.          mov _vcfreq[ebp*2],ax
  751.          or _vccmnd[ebp],freq
  752.          jmp fx_doneeffect
  753. fx_arp:
  754.          cmp dh,0                           ; arpeggio
  755.          jne fx_more_effects
  756.  
  757.          xor ebx,ebx
  758.          mov bl,byte ptr [ebp*8+arp]
  759.          mov ax,word ptr [ebp*8+arp+ebx+2]
  760.          mov _vcfreq[ebp*2],ax
  761.          or _vccmnd[ebp],freq
  762.          add bl,2
  763.          cmp bl,6
  764.          jb short fx_setarp
  765.          xor bl,bl
  766. fx_setarp:
  767.          mov byte ptr [ebp*8+arp],bl
  768.          jmp fx_doneeffect
  769.  
  770. fx_more_effects:
  771.  
  772. ; Put more effects here
  773.  
  774. ; dh = effect
  775. ; dl = data
  776.  
  777. fx_doneeffect:
  778.          dec ebp
  779.          jnl fx_mainloop
  780.  
  781.          ret
  782.  
  783. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  784. ; Init mod player
  785. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  786. _mod_init:
  787.          ret                                ; nothing to init!
  788.  
  789. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  790. ; Reset mod player
  791. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  792. _mod_uninit:
  793.          call _mod_stop
  794.          ret
  795.  
  796. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  797. ; Load a mod, samples go directly into GUS ram
  798. ; In:
  799. ;   EAX -> stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
  800. ;   EDX -> buffer large enough for all music data plus largest sample
  801. ; _sfxmem -> location to begin storing on GUS memory
  802. ; Out:
  803. ;  CF = 1 mod not recognized!
  804. ;  CF = 0 mod loaded ok!
  805. ;   EAX - number of bytes of buffer to keep
  806. ;   EBX - number of bytes used on GUS
  807. ; _sfxmem -> next free GUS memory location
  808. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  809.  
  810. _mod_load:
  811.          pushad
  812.          mov sambase,edx
  813.          mov ecx,1084
  814.          call eax
  815.  
  816.          mov eax,4
  817.          mov ebx,[edx+1080]
  818.  
  819.          cmp ebx,"4TLF"
  820.          je ml_foundtype
  821.          cmp ebx,".K.M"
  822.          je ml_foundtype
  823.          cmp ebx,"!K!M"
  824.          je ml_foundtype
  825.  
  826.          mov al,6
  827.          cmp ebx,"6TLF"
  828.          je ml_foundtype
  829.          cmp ebx,"NHC6"
  830.          je ml_foundtype
  831.  
  832.          mov al,8
  833.          cmp ebx,"8TLF"
  834.          je ml_foundtype
  835.          cmp ebx,"NHC8"
  836.          je ml_foundtype
  837.  
  838.          popad                              ; unknown module type
  839.          stc
  840.          ret
  841.  
  842. ml_foundtype:
  843.          mov ordwidth,eax
  844.  
  845.          mov al,[edx+950]
  846.          mov lastord,al
  847.  
  848.          mov ecx,31
  849.          lea esi,[edx+20]
  850.          mov edi,edx
  851.  
  852. ml_sampledata:
  853.          movzx eax,word ptr [esi+22]
  854.          xchg ah,al
  855.          shl eax,1
  856.          stosd                              ; sample length
  857.  
  858.          movzx eax,word ptr [esi+24]
  859.          stosd
  860.  
  861.          movzx eax,word ptr [esi+26]
  862.          xchg ah,al
  863.          shl eax,1
  864.          stosd                              ; sample repeat start
  865.  
  866.          movzx eax,word ptr [esi+28]
  867.          xchg ah,al
  868.          shl eax,1
  869.          stosd                              ; repeat length
  870.  
  871.          add esi,30
  872.          loop ml_sampledata
  873.  
  874.          mov ordbase,edi
  875.  
  876.          mov ecx,128
  877.          lea esi,[edx+952]
  878.          xor al,al
  879. ml_rep:
  880.          mov ah,[esi]                       ; copy pattern order
  881.          mov [edi],ah                       ; and find highest pattern number
  882.          cmp ah,al
  883.          jb ml_notl
  884.          mov al,ah
  885. ml_notl:
  886.          inc esi
  887.          inc edi
  888.          loop ml_rep
  889.  
  890.          mov patterns,edi
  891.  
  892.          inc al
  893.          mov ordsize,al
  894.  
  895.          mov edx,edi
  896.          mov ecx,ordwidth
  897.          shl ecx,6+2
  898.          movzx eax,ordsize
  899.          imul ecx,eax
  900.          call dword ptr [esp+28]
  901.  
  902.          add edx,ecx
  903.          mov patternend,edx
  904.  
  905.          mov ebx,_sfxmem
  906.          mov esi,sambase
  907.          mov edi,31
  908.          mov _sfxsign,80h
  909. ml_loop1:
  910.          mov ecx,[esi]                      ; [esi+0]  = length
  911.          jcxz ml_nextsample                 ; [esi+8]  = repeat start
  912.          cmp ecx,[esi+12]                   ; [esi+12] = repeat length
  913.          ja ml_nofixl                       ; ebx = GUS memory, ecx = length
  914.          mov [esi+12],ecx
  915. ml_nofixl:
  916.          mov eax,[esi+8]
  917.          add eax,[esi+12]
  918.          cmp eax,ecx
  919.          jb mr_nofixr
  920.          mov eax,ecx
  921.          sub eax,[esi+12]
  922.          mov [esi+8],eax
  923. mr_nofixr:
  924.          mov ebp,ecx
  925.  
  926.          mov eax,[esi+12]
  927.          cmp eax,4
  928.          jb short ml_noloop
  929.  
  930.          or byte ptr [esi+4+2],loop_on+loop_bi
  931.          mov ebp,eax
  932.          add ebp,[esi+8]
  933.  
  934. ml_noloop:
  935.          mov [esi],ebx
  936.          add [esi+8],ebx
  937.          add ebp,ebx
  938.          mov [esi+12],ebp
  939.  
  940.          call dword ptr [esp+28]
  941.          call _sfx_putram
  942.          add ebx,ecx
  943.  
  944. ml_nextsample:
  945.          add esi,4*4
  946.          dec edi
  947.          jnz ml_loop1
  948.  
  949.          mov edx,sambase
  950.          sub edx,patternend
  951.  
  952.          mov [esp+28],edx
  953.          mov [esp+16],ebx                   ; save amount of GUS ram used for samples
  954.          add _sfxmem,ebx
  955.  
  956.          mov ebp,57
  957.  
  958.          xor eax,eax
  959. ml_findpitch:
  960.          cmp bp,periods[eax*2]
  961.          jae ml_set_freq
  962.          inc eax
  963.          cmp eax,930
  964.          jne ml_findpitch
  965. ml_set_freq:
  966.          mov ax,rawfreq[eax*2]
  967.          call _sfx_getfreq
  968.          mov ecx,ebp
  969.          sub ecx,57
  970.          and ecx,0fffeh
  971.          mov pitchtbl[ecx],ax
  972.          add ebp,2
  973.          xor eax,eax
  974.          cmp ebp,1713
  975.          jb ml_findpitch
  976.  
  977.          popad
  978.          clc                                ; clc = mod OK!
  979.          ret
  980.  
  981. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  982. ; Play a loaded mod
  983. ; In:
  984. ;  EAX = routine to call when done module
  985. ;     eg: _ret      = loop module forever.
  986. ;         _mod_stop = stop module when done
  987. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  988. _mod_play:
  989.          push eax ecx edi esi
  990.          call _mod_stop
  991.          mov whendone,eax
  992.          mov _ordmod,0
  993.          mov tempo,6
  994.          mov tempoc,1
  995.          mov panloc,0
  996.          mov rowleft,64
  997.          mov _currow,0
  998.          mov esi,ordbase
  999.          movzx eax,byte ptr [esi]
  1000.          shl eax,10
  1001.          add eax,patterns
  1002.          mov currow,eax
  1003.  
  1004.          call _irq_findcontrol
  1005.          jc short mp_nomod
  1006.          mov _irqcontrol[ecx*4],offset mr_modpolling
  1007.          mov whichmodcontrol,ecx
  1008. mp_nomod:
  1009.          xor eax,eax
  1010.  
  1011.          mov edi,offset effect
  1012.          mov ecx,8
  1013.          rep stosw
  1014.  
  1015.          mov edi,offset cursamp
  1016.          mov ecx,152
  1017.          rep stosb
  1018.  
  1019.          mov edi,offset modvol
  1020.          mov eax,64
  1021.          mov ecx,8
  1022.          rep stosb
  1023.  
  1024.          pop esi edi ecx eax
  1025.          clc
  1026.          ret
  1027.  
  1028. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1029. ; Stop playback
  1030. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1031. _mod_stop:
  1032.          push ecx
  1033.          mov dword ptr _vcvol[0],0000000h
  1034.          mov dword ptr _vcvol[4],0000000h
  1035.          mov dword ptr _vccmnd[0],20202020h
  1036.          mov dword ptr _vccmnd[4],20202020h
  1037.          mov ecx,whichmodcontrol
  1038.          or ecx,ecx
  1039.          jl ms_ret
  1040.          mov _irqcontrol[ecx*4],offset _ret
  1041.          mov whichmodcontrol,-1
  1042. ms_ret:
  1043.          pop ecx
  1044.          ret
  1045.  
  1046. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1047. ; Play mod sample # al
  1048. ; In: AL sample play
  1049. ;   DL = channel (0-31)
  1050. ;   BL = volume  (0-15)
  1051. ;   BH = pan     (0-8)
  1052. ;   CH = precalculated frequency (0-59)
  1053. ; Out:
  1054. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1055.  
  1056. _mod_sample_play:
  1057.          pushad
  1058.          movzx eax,al
  1059.          mov esi,sambase
  1060.  
  1061.          shl eax,4
  1062.          add esi,eax
  1063.          mov edi,[esi]
  1064.          mov eax,[esi+8]
  1065.          mov ebp,[esi+12]
  1066.  
  1067.          mov _vcsbeg[edx*4],edi
  1068.          mov _vclbeg[edx*4],eax
  1069.          mov _vclend[edx*4],ebp
  1070.          mov cl,byte ptr [esi+4+2]
  1071.  
  1072.          mov _vcpan[edx],bh
  1073.          mov _vcvol[edx],bl
  1074.          movzx eax,ch
  1075.          mov ax,_freqtbl[eax*2]
  1076.          mov _vcfreq[edx*2],ax
  1077.          mov _vccntrl[edx],cl
  1078.          mov _vccmnd[edx],play              ; command comes last
  1079.          popad
  1080.          ret
  1081.  
  1082. code32   ends
  1083.          end
  1084.